﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Nsf.Samples.RetryActivitySample.Infrastructure.Actions
{
    public abstract class ActionBase : IAction
    {
        #region Internal Methods

        private Dictionary<String, String> ParseArguments(ICollection<String> knownArguments, params String[] args)
        {
            var result = new Dictionary<String, String>(StringComparer.InvariantCultureIgnoreCase);
            Int32 i;
            for (i = 1; i < args.Length - 1; i++)
            {
                var key = args[i];
                if (knownArguments.Contains(key) && !result.ContainsKey(key))
                {
                    if (!knownArguments.Contains(args[i + 1]))
                    {
                        result.Add(key, args[i + 1]);
                        i++;
                    }
                    else
                    {
                        result.Add(key, String.Empty);
                    }
                }
            }
            if (i == args.Length - 1 && knownArguments.Contains(args[i]))
            {
                result.Add(args[i], String.Empty);
            }
            return result;
        }

        #endregion

        #region Overrideable Methods

        protected virtual ICollection<String> GetKnownArguments()
        {
            return new HashSet<String>(StringComparer.InvariantCultureIgnoreCase) {"help"};
        }

        protected abstract void ValidateArguments(IDictionary<String, String> args);

        protected abstract void OnExecute(IDictionary<String, String> args);

        protected abstract void OnHelp();

        #endregion

        #region Public methods

        public virtual void Execute(params String[] args)
        {
            var knownArguments = GetKnownArguments();
            var parsedArguments = ParseArguments(knownArguments, args);
            ValidateArguments(parsedArguments);
            if (parsedArguments.ContainsKey("help"))
                OnHelp();
            else 
                OnExecute(parsedArguments);
        }

        #endregion
    }
}
